//
//  HBBaseRequest.m
//  HeartBeat
//
//  Created by karong on 2023/8/23.
//

#import "HBBaseRequest.h"
#import "AFNetworking.h"
#import "GTMBase64.h"
#import "NSData+AES.h"

@implementation HBBaseRequest
+ (void)postWithURLString:(nonnull NSString *)URLString parameters:(nonnull id)parameters success:(nonnull void (^)(NSDictionary * _Nonnull __strong))success failure:(失败回调)failure {
    parameters = [self fullParameters:parameters url:URLString];
    parameters = [self encryption:parameters];
    [self requestWithMethod:@"POST"
                  URLString:FULL_ADDRESS(URLString)
                       head:parameters
                 parameters:parameters
                    success:success
                    failure:failure];
}

+ (void)postAppleOrderWithURLString:(NSString *)URLString
              parameters:(id)parameters
                 success:(void (^)(NSDictionary *dataDict))success
                 failure:(失败回调)failure {
    parameters = [self fullParameters:parameters url:URLString];
    NSDictionary * header = [self encryption:parameters];
    [self requestWithMethod:@"POST"
                  URLString:FULL_ADDRESS(URLString)
                       head:header
                 parameters:parameters
                    success:success
                    failure:failure];
}



+ (void)requestWithMethod:(NSString *)method URLString:(NSString *)URLString head:(id)header parameters:(id)parameters success:(回调一个字典)success failure:(失败回调)failure {
    AFHTTPSessionManager *manager = [self defaultAFSessionManager];
    if (parameters) {
        for (NSString *key in ((NSDictionary *)header).allKeys) {
            NSString *value = header[key];
            [manager.requestSerializer setValue:value forHTTPHeaderField:key];
        }
    }
    NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:method
                                                                      URLString:URLString
                                                                     parameters:parameters
                                                                          error:nil];
    NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
        NSHTTPURLResponse *urlResponse = (NSHTTPURLResponse *)response;
        NSDictionary *responseValue = (NSDictionary *)responseObject;
        if (![responseObject isKindOfClass:[NSDictionary class]]){
            NSString * responseContent =[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
            NSData *jsonData = [responseContent dataUsingEncoding:NSUTF8StringEncoding];
            responseValue = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
        }
        if (responseValue) {
            NSInteger resultCode = [responseValue[@"ret"] integerValue];
            if (resultCode == 200) {
                NSDictionary *dataDict;
                NSString *dataStr =  responseValue[@"data"];
                //判斷是否是加密數据
                if ([dataStr isKindOfClass:[NSDictionary class]]) {
                    NSError *parseError;
                    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:responseValue options:NSJSONWritingPrettyPrinted error:&parseError];
                    if (jsonData) {
                        dataDict = [NSJSONSerialization JSONObjectWithData:jsonData
                                                                   options:NSJSONReadingMutableContainers
                                                                     error:nil];
                    }
                }else{
                    ///解密
                    NSData *data4 = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
                    data4 = [GTMBase64 decodeData:data4];
                    NSData *data5 = [data4 AES128DecryptWithKey:appConfig.aes_key iv:appConfig.aes_iv];
                    if (data5) {
                        dataDict = [NSJSONSerialization JSONObjectWithData:data5
                                                                   options:NSJSONReadingMutableContainers
                                                                     error:nil];
                    }
                }
                if (success) {
                    success(dataDict);
                }
            }
            else {
                error = error ? error : [NSError errorWithDomain:responseValue[@"msg"] ?: @"" code:resultCode ?: urlResponse.statusCode userInfo:nil];
                if (failure) {
                    failure(urlResponse, error, responseValue);
                }
                [self requestFailureWithURLString:URLString parameters:parameters statusCode:urlResponse.statusCode responseObject:responseObject resultCode:resultCode error:error log:YES];
            }
        }
        else {
            if (responseObject && !error) {
                error = [NSError errorWithDomain:@"Network error. Please try again later" code:NSURLErrorCannotDecodeContentData userInfo:nil];
            }
            if (failure) {
                failure(urlResponse, error, responseObject);
            }
            [self requestFailureWithURLString:URLString parameters:parameters statusCode:urlResponse.statusCode responseObject:responseObject resultCode:0 error:error log:YES];
        }
    }];
    [dataTask resume];
}

+ (void)postWithURLString:(NSString *)URLString
               parameters:(id)parameters
                fileDatas:(NSArray<NSData *> *)fileDatas
                fileNames:(NSArray<NSString *> *)fileNames
                  success:(回调一个字典)success
                  failure:(失败回调)failure
{
    parameters = [self fullParameters:parameters url:URLString];
    [self postWithURLString:FULL_ADDRESS(URLString) parameters:parameters names:fileNames fileDatas:fileDatas fileNames:fileNames success:success failure:failure];
}


///圖片上傳
+ (void)postWithURLString:(NSString *)URLString
               parameters:(id)parameters
                    names:(NSArray<NSString *> *)names
                fileDatas:(NSArray<NSData *> *)fileDatas
                fileNames:(NSArray<NSString *> *)fileNames
                  success:(回调一个字典)success
                  failure:(失败回调)failure {
    [AFHTTPSessionManager manager].requestSerializer.timeoutInterval = 60;
    [[AFHTTPSessionManager manager] POST:URLString parameters:parameters headers:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        for (int i = 0; i < fileDatas.count; i ++) {
            [formData appendPartWithFileData:fileDatas[i] name:@"file" fileName:fileNames[i] mimeType:@"image/jpeg"];
        }
    } progress:^(NSProgress * _Nonnull uploadProgress) {
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSDictionary *responseValue = (NSDictionary *)responseObject;
        if (![responseObject isKindOfClass:[NSDictionary class]]){
            NSString * responseContent =[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
            NSData *jsonData = [responseContent dataUsingEncoding:NSUTF8StringEncoding];
            responseValue = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
        }
        NSInteger resultCode = [responseValue[@"ret"] integerValue];
        NSError * error;
        if (responseValue) {
            if (resultCode == 200) {
                NSDictionary *dataDict;
                NSString *dataStr =  responseValue[@"data"];
                if ([dataStr isKindOfClass:[NSDictionary class]]) {
                    NSError *parseError;
                    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:responseValue options:NSJSONWritingPrettyPrinted error:&parseError];
                    if (jsonData) {
                        dataDict = [NSJSONSerialization JSONObjectWithData:jsonData
                                                                   options:NSJSONReadingMutableContainers
                                                                     error:nil];
                    }
                }else{
                    ///解密
                    NSData *data4 = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
                    data4 = [GTMBase64 decodeData:data4];
                    NSData *data5 = [data4 AES128DecryptWithKey:appConfig.aes_key iv:appConfig.aes_iv];
                    if (data5) {
                        dataDict = [NSJSONSerialization JSONObjectWithData:data5
                                                                   options:NSJSONReadingMutableContainers
                                                                     error:nil];
                    }
                }
                success(dataDict);
            }
            else {
                error = task.error ? task.error : [NSError errorWithDomain:responseValue[@"msg"] ?: @"" code:resultCode ?: task.error.code userInfo:nil];
                if (failure) {
                    failure(task.response, error, responseValue);
                }
                [self requestFailureWithURLString:URLString parameters:parameters statusCode:task.error.code responseObject:responseObject resultCode:resultCode error:error log:YES];
            }
        }
        else {
            if (responseObject && !error) {
                error = [NSError errorWithDomain:@"Network error. Please try again later" code:NSURLErrorCannotDecodeContentData userInfo:nil];
            }
            if (failure) {
                failure(task.response, error, responseValue);
            }
            [self requestFailureWithURLString:URLString parameters:parameters statusCode:task.error.code responseObject:responseObject resultCode:resultCode error:error log:YES];
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
    }];
    return;
}

+ (void)requestFailureWithURLString:(NSString *)URLString parameters:(id)parameters statusCode:(NSInteger)statusCode responseObject:(id)responseObject resultCode:(NSInteger)resultCode error:(NSError *)error log:(BOOL)log {
    if (resultCode == 400) {
        NSString * string = error.localizedDescription;
        if ([string.lowercaseString containsString:@"token"]) {
            UIViewController * vc = [UIViewController currentViewController];
            if (![vc isKindOfClass:NSClassFromString(@"HBBaseReadController")]) {
                [ViewManager showLoginVCInController:[UIViewController currentViewController]];
                [HBToast simple:WSLocalized(@"還沒有登錄哦~請先登錄")];
            }
        }
        else {
            [HBToast simple:error.localizedDescription];
        }
    }
    else if (resultCode == 401) {
        [appUserCenter logOut];
        [HBToast simple:WSLocalized(@"長期未登錄，請重新登錄")];
    }
    else if (resultCode == 466) {
    }
    else {
        [HBToast simple:error.localizedDescription];
    }
}
#pragma mark - 頭部信息
+ (NSMutableDictionary *)fullParameters:(NSDictionary*)parameters url:(NSString *)urlString{
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    dict[@"version_code"] = [HBTool getVersionCode];
    dict[@"os_type"] = @"ios";
    dict[@"channel"] = @"AppStore";
    dict[@"lang_type"] = SF(@"%ld", appConfig.languageType);
//    dict[@"lang_type"] = @"1";
    dict[@"package"] = [[NSBundle mainBundle] infoDictionary][@"CFBundleIdentifier"];
    if (!KIsNullOrEmpty(appUserCenter.token)) {
        dict[@"token"] = KEmptyStr(appUserCenter.token);
    }
    dict[@"service"] = urlString;
    dict[@"user_id"] = SF(@"%ld", (long)appUserCenter.id);
    dict[@"brand"] = @"iPhone";
    dict[@"model"] = [HBTool phoneModel];
    dict[@"sys"] = [[UIDevice currentDevice] systemVersion];
    [dict addEntriesFromDictionary:parameters];
    return dict;
}

+ (NSMutableDictionary *)encryption:(NSMutableDictionary *)dict {
    //加密
    NSString * parStr = [dict jsonStringEncoded];
    //使用aes-128-cbc对参數进行加密
    NSData *data1 = [parStr dataUsingEncoding:NSUTF8StringEncoding];
    data1 = [data1 AES128EncryptWithKey:appConfig.aes_key iv:appConfig.aes_iv];

    NSData *data2 = [GTMBase64 encodeData:data1];
    NSString *dataStr = [[NSString alloc] initWithData:data2 encoding:NSUTF8StringEncoding];
    
    NSMutableDictionary *parDic = [NSMutableDictionary new];
    parDic[@"data"] = dataStr?dataStr:@"";
    return parDic;
}

+ (AFHTTPSessionManager *)defaultAFSessionManager {
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    manager.requestSerializer.timeoutInterval = 13.f;
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/plain", @"text/html", nil];
    return manager;
}
@end
